-
Notifications
You must be signed in to change notification settings - Fork 254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add LiveImage support #754
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: hardys The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
@hardys: GitHub didn't allow me to request PR reviews from the following users: sacharya. Note that only metal3-io members and repo collaborators can review this PR, and authors cannot review their own PRs. In response to this:
Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
} | ||
|
||
// image_source | ||
func (p *ironicProvisioner) getImageUpdateOptsForNode(ironicNode *nodes.Node, imageData *metal3v1alpha1.Image, liveImageData *metal3v1alpha1.LiveImage) (updates nodes.UpdateOpts, err error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inside this method we have the information we need to derive imageData and liveImageData, so we shouldn't need to pass them as arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I did this is because since 2e4e00b from @zaneb the imageData is potentially different depending on where it's called - in ValidateManagementAccess
it could use the Status
image on adopt, but when called via setUpForProvisioning->getUpdateOptsForNode we'll only ever want to use the Spec
?
I wasn't sure if unconditionally doing that check against the status was safe, so I tried to replicate the existing logic, I was worried about introducing a new corner case in addition to the one @zaneb was fixing..
Co-Authored-By: Sudarshan Acharya <[email protected]>
@dhellmann you asked for details of how I'm testing this: metal3-io/metal3-dev-env#579 applied and This should result in a locally cached FCOS iso:
Then I'm running
Then applying the change e.g:
Currently that doesn't result in any state change, the BMH remains in |
@@ -293,16 +293,25 @@ func (hsm *hostStateMachine) provisioningCancelled() bool { | |||
if hsm.Host.HasError() { | |||
return true | |||
} | |||
if hsm.Host.Spec.Image == nil { | |||
if hsm.Host.Spec.Image == nil && hsm.Host.Spec.LiveImage == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is very similar to the BMH NeedsProvisioning() - I wonder if we could use the inverse of that here instead of duplicating nearly the same conditionals?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to be the NeedsDeprovisioning() method; we moved it here because having methods on the BMH object is actually bad. They're not inverses of each other.
if host.Spec.Image.URL == "" { | ||
// We have an Image struct but it is empty | ||
return false | ||
if host.Spec.LiveImage != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We may need to make the logic in this function a bit more complicated to deal with switching a host from live image to provisioned image, because in that case we may have a non-nil pointer to a struct with an empty string for the live image and we would want to treat that as though the image was set. We can probably deal with that case in another PR, after we have the basic case working.
/retitle Add LiveImage support |
Ok testing locally this seems to be working now - so I removed the WIP but we need to decide if the case of switching from Image->LiveImage or LiveImage->Image needs to be handled here or in a followup (I've not tested that yet, just adding LiveImage where there is no existing Image |
/cc @zaneb ptal when you get a moment, thanks! |
I'd be happy to have that work in a follow-up PR, to make things easier to review. |
/test-integration |
@@ -293,16 +293,25 @@ func (hsm *hostStateMachine) provisioningCancelled() bool { | |||
if hsm.Host.HasError() { | |||
return true | |||
} | |||
if hsm.Host.Spec.Image == nil { | |||
if hsm.Host.Spec.Image == nil && hsm.Host.Spec.LiveImage == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This used to be the NeedsDeprovisioning() method; we moved it here because having methods on the BMH object is actually bad. They're not inverses of each other.
return true | ||
} | ||
if hsm.Host.Status.Provisioning.Image.URL == "" { | ||
if hsm.Host.Spec.LiveImage != nil && hsm.Host.Status.Provisioning.LiveImage.URL == "" { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't handle the case where Spec.LiveImage is set and Status.Provisioning.Image.URL is also set, in which case we want to return true.
Similarly, below we don't handle the case where Spec.Image is set and Status.Provisioning.LiveImage.URL is also set.
I think the correct logic is something like:
switch {
case hsm.Host.Spec.LiveImage != nil:
if hsm.Host.Spec.LiveImage.URL == "" {
return true
}
if hsm.Host.Status.Provisioning.Image.URL != "" {
return true
}
if hsm.Hosts.Status.Provisioning.LiveImage.URL == "" {
return false
}
if hsm.Host.Spec.LiveImage != nil && hsm.Host.Spec.LiveImage.URL != hsm.Host.Status.Provisioning.LiveImage.URL {
return true
}
}
case hsm.Host.Spec.Image != nil:
if hsm.Host.Spec.Image.URL == "" {
return true
}
if hsm.Host.Status.Provisioning.LiveImage.URL != "" {
return true
}
if hsm.Host.Status.Provisioning.Image.URL == "" {
return false
}
if hsm.Host.Spec.Image.URL != hsm.Host.Status.Provisioning.Image.URL {
return true
}
default:
return true
}
return false
Assuming that hsm.Host.Spec.LiveImage
and hsm.Host.Spec.Image
cannot both be non-nil. If they both can be non-nil it quickly devolves even further into a nightmare. Seeing all this duplicated/permuted logic makes me wonder whether we should just have an ISO flag in the regular Image struct instead. At least in the Status maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review @zaneb - In the docstring I do mention that only Image or LiveImage should be set, but I agree long term they should be validated as mutually exclusive.
Re the ISO flag, that was my original proposal but this approach was preferred since it's possible we might support a live kernel/ramdisk in future, and the checksum argument to the current Image section currently isn't applicable to the LiveImage case: metal3-io/metal3-docs#150 (comment)
} else { | ||
op = nodes.ReplaceOp | ||
p.log.Info("updating boot_iso") | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we also need to remove any options corresponding to the other type of image?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I think there are several corner cases in the Image->LiveImage and LiveImage->Image case which I've not yet tested or accounted for in the code.
I can attempt to do that in this PR, or as previously mentioned by @dhellmann we might want to land this first iteration then take care of that as a followup, so it's easier to review?
/hold after discussion I'm working on an alternative version which uses the Image DiskFormat option, then we can compare and decide which interface to go with (the DiskFormat approach should be significantly simpler than that in this PR and avoid some of the corner cases discussed in the review comments) |
Closing in favor of #759 |
First-pass of implementation related to metal3-io/metal3-docs#150